package com.likerSai;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 四数之和
 * 尚可优化
 *
 * @author sun.ye
 * @since 2021-07-27 17:48
 */
public class FourSum {


    public static void main(String[] args) {
//        List<List<Integer>> result = fourSum(new int[]{34,55,79,28,46,33,2,48,31,-3,84,71,52,-3,93,15,21,-43,57,-6,86,56,94,74,83,-14,28,-66,46,-49,62,-11,43,65,77,12,47,61,26,1,13,29,55,-82,76,26,15,-29,36,-29,10,-70,69,17,49},3);
        List<List<Integer>> result = fourSum(new int[]{1,0,-1,0,-2,2},0);
        for (List<Integer> item: result) {
            System.out.println(item);
        }

    }


    public static List<List<Integer>> fourSum(int[] nums, int target) {

        List<List<Integer>> result = new ArrayList<>();
        List<Integer> resultItem;
        Arrays.sort(nums);

        int first,second,third,idxThird,last,idxLast,sum,length = nums.length;

        for (int i = 0; i < length - 3; i++ ) {
            first = nums[i];
            if (i > 0 && first == nums[i-1]){
                continue;
            }
            for (int j = i + 1; j < length - 2; j++) {
                second = nums[j];
                if ((j > i+1) && second == nums[j-1]){
                    continue;
                }
                idxThird = j + 1;
                third = nums[idxThird];
                idxLast = length - 1;
                last = nums[idxLast];

                while (idxThird < idxLast){
                    if ((idxThird > j+1) && third == nums[idxThird-1]){
                        third = nums[++idxThird];
                        continue;
                    }
                    if ((idxLast < length - 1) && last == nums[idxLast+1]){
                        last = nums[--idxLast];
                        continue;
                    }

                    sum = first + second + third + last;

                    if (sum < target){
                        third = nums[++idxThird];
                    }else if (sum > target){
                        last = nums[--idxLast];
                    }else {
                        resultItem = new ArrayList<>();
                        resultItem.add(first);
                        resultItem.add(second);
                        resultItem.add(third);
                        resultItem.add(last);
                        result.add(resultItem);
                        third = nums[++idxThird];
                        last = nums[--idxLast];
                    }
                }
            }
        }

        return result;
    }
}